package com.eds.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.txlcn.tc.annotation.TccTransaction;
import com.eds.dto.BackOrderDTO;
import com.eds.dto.BackOrdersBoardDTO;
import com.eds.dto.DashboardTrendsDTO;
import com.eds.dto.PageUtils;
import com.eds.exception.BusException;
import com.eds.feign.CourseFeign;
import com.eds.feign.UserService;
import com.eds.mapper.OrdersMapper;
import com.eds.pojo.BaseResult;
import com.eds.pojo.CodeEnum;
import com.eds.pojo.MyMessage;
import com.eds.rabbitmeq.utils.SendMessageUtils;
import com.eds.service.OrdersService;
import com.eds.utils.DateTimeUtils;
import com.eds.utils.SnowflakeIdGenerator;
import com.pojo.Course;
import com.pojo.Notification;
import com.pojo.Orders;
import com.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 34195
 * @description 针对表【order】的数据库操作Service实现
 * @createDate 2025-03-31 21:05:09
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>
        implements OrdersService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private UserService userService;

    @Autowired
    private CourseFeign courseFeign;
    @Autowired
    private SendMessageUtils sendMessageUtils;
    @Autowired
    private SnowflakeIdGenerator idGenerator;


    /* *
     * @Title: createOrder
     * @Author: vvSmile
     * @Date: 2025-04-01 18:08:47
     * @param order
     * @return Boolean
     * @Description: TODO 创建订单
     */
    @Override
    public Boolean createOrders(Orders orders) {
        int insert = ordersMapper.insert(orders);
        return insert > 0;
    }


    /* *
     * @Title: selectOrdersByOrdersId
     * @Author: vvSmile
     * @Date: 2025-04-02 10:31:12
     * @param ordersId
     * @return Orders
     * @Description: TODO 根据ordersId查询订单
     */
    @Override
    public Orders selectOrdersByOrdersId(String ordersId) {
        Orders orders = ordersMapper.selectById(ordersId);
        return orders;
    }


    /* *
     * @Title: cancelOrders
     * @Author: vvSmile
     * @Date: 2025-04-02 10:31:24
     * @param orders
     * @return Boolean
     * @Description: TODO 取消订单
     */
    @Override
    public Boolean cancelOrders(String ordersId) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("orders_id", ordersId);
        int i = ordersMapper.delete(ordersQueryWrapper);
        return i > 0;
    }


    /* *
     * @Title: updateOrdersPayStatus
     * @Author: vvSmile
     * @Date: 2025-04-03 18:09:00
     * @param ordersId
     * @param tradeNo
     * @param buyerLogonId
     * @param buyerPayAmount
     * @return Boolean
     * @Description: TODO 更新支付状态
     */
    @Override
    public Boolean updateOrdersPayStatus(String ordersId, String paymentChannel, String tradeNo, String buyerLogonId, String buyerPayAmount) {
        UpdateWrapper<Orders> uoUpdateWrapper = new UpdateWrapper<Orders>()
                .set("transaction_id", tradeNo)
                .set("payment_amount", buyerPayAmount)
                .set("status", 1)
                .set("payment_channel", paymentChannel)
                .eq("orders_id", ordersId)
                .set("pay_time", LocalDateTime.now());
        int update = ordersMapper.update(null, uoUpdateWrapper);
        return update > 0;
    }


    /* *
     * @Title: selectOrdersByScheduleUserCourseId
     * @Author: vvSmile
     * @Date: 2025-04-06 19:58:24
     * @param scheduleId
     * @param userId
     * @param courseId
     * @return Orders
     * @Description: TODO 根据排课id、用户id、课程id查询订单
     */
    @Override
    public Orders selectOrdersByScheduleUserCourseId(Long scheduleId, Long userId, Long courseId) {
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<Orders>()
                .eq("schedule_id", scheduleId)
                .eq("user_id", userId)
                .eq("status", 1)
                .eq("course_id", courseId);
        Orders orders = ordersMapper.selectOne(ordersQueryWrapper);
        return orders;
    }


    /* *
     * @Title: refundAndCancelBooking
     * @Author: vvSmile
     * @Date: 2025-04-07 10:20:10
     * @param token
     * @param ordersId
     * @return BaseResult
     * @Description: TODO 退款并取消预约
     */
    @Override
    @TccTransaction
    @Transactional
    public BaseResult refundAndCancelBooking(String token, String scheduleId) {
        //获取用户信息
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        //根据ordersId查询订单
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("schedule_id", scheduleId);
        Orders orders = ordersMapper.selectOne(ordersQueryWrapper);
        if (orders == null || userId.equals(orders.getOrdersId())) {
            return BaseResult.error(CodeEnum.ORDERS_SELECT_ERROR);
        }
        //退款（非免费）
        if (!orders.getPaymentAmount().equals(0)) {
            //调用支付宝退款接口
            /*BaseResult baseResult = payFeign.refund(orders.getPaymentAmount().multiply(new java.math.BigDecimal(100)).longValue() + "", orders.getTransactionId());
            if (!baseResult.isSuccess()){
                return BaseResult.error(CodeEnum.ORDERS_REFUND_ERROR);
            } */
            //更新订单状态
            UpdateWrapper<Orders> ordersUpdateWrapper = new UpdateWrapper<>();
            //支付宝用用返回值后，添加其他数据
            ordersUpdateWrapper.set("status", 2)
                    .eq("orders_id", orders.getOrdersId());
            //更新teacher_schedule表状态
            int updateOrders = ordersMapper.update(null, ordersUpdateWrapper);
            //更新预约状态
            int updateBooking = courseFeign.updateBookingStatus(orders.getScheduleId(), 2);
            //更新teacher_schedule表状态
            int updateSchedule = userService.updateScheduleStatus(orders.getScheduleId(), 0);
            if (updateOrders > 0 && updateBooking > 0 && updateSchedule > 0) {
                //return BaseResult.ok("取消预约成功！",baseResult);
                return BaseResult.ok("取消预约成功！");
            }
            return BaseResult.error(CodeEnum.ORDERS_REFUND_ERROR);
        } else {
            //更新订单状态
            UpdateWrapper<Orders> ordersUpdateWrapper = new UpdateWrapper<>();
            ordersUpdateWrapper.set("status", 2)
                    .eq("orders_id", orders.getOrdersId());
            int updateOrders = ordersMapper.update(null, ordersUpdateWrapper);
            //更新预约状态
            int updateBooking = courseFeign.updateBookingStatus(orders.getScheduleId(), 2);
            //更新teacher_schedule表状态
            int updateSchedule = userService.updateScheduleStatus(orders.getScheduleId(), 2);
            if (updateOrders > 0 && updateBooking > 0 && updateSchedule > 0) {
                //return BaseResult.ok("取消预约成功！",baseResult);
                return BaseResult.ok("订单退款成功！");
            }
            return BaseResult.error(CodeEnum.ORDERS_REFUND_ERROR);
        }
    }


    /* *
     * @Title: updateOrdersPayFreeStatus
     * @Author: vvSmile
     * @Date: 2025-04-07 20:49:17
     * @param ordersId
     * @param paymentAmount
     * @param paymentChannel
     * @param transactionId
     * @return int
     * @Description: TODO 更新免费订单
     */
    @Override
    public Orders updateOrdersPayFreeStatus(String ordersId, BigDecimal paymentAmount, String paymentChannel, String transactionId) {
        UpdateWrapper<Orders> uoUpdateWrapper = new UpdateWrapper<Orders>()
                .set("transaction_id", "xxx0011")
                .set("payment_amount", 0.00)
                .set("status", 1)
                .set("payment_channel", "alipay")
                .eq("orders_id", ordersId);
        int update = ordersMapper.update(null, uoUpdateWrapper);
        Orders orders = ordersMapper.selectById(ordersId);
        return orders;
    }

    @Override
    public Void sendOrdersPaySuccessMessage(String token, String ordersId) {
        //查询订单信息
        Orders orders = ordersMapper.selectById(ordersId);
        Course course = courseFeign.ordersSelectCourseByScheduleId(token, orders.getScheduleId());
        DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        String date = now.format(dateTimeFormat);
        String link = "www.tencentMeeting45645125465scascsacsa.com";
        String strNotificationContent = "尊敬的用户，\n" +
                "\n" +
                "您好！\n" +
                "\n" +
                "感谢您购买《" + course.getTitle() + "》课程。我们很高兴地通知您，您的订单已成功支付完成。\n" +
                "\n" +
                "订单详情如下：\n" +
                "订单编号：" + orders.getOrdersId() + "\n" +
                "支付时间：" + date + "\n" +
                "付款金额：" + course.getPrice() + "\n" +
                "上课链接：" + link + "\n" +
                "\n" +
                "请及时关注您的课程进度，如有疑问，请随时联系我们。\n" +
                "\n" +
                "再次感谢您的支持，祝您学习愉快！\n" +
                "\n" +
                "Eds团队";
        //通过雪花算法生成课程ID
        String notificationId = idGenerator.nextShortId(14);
        Notification notification = new Notification();
        notification.setNotificationId(notificationId);
        notification.setTitle("订单支付成功通知");
        notification.setContent(strNotificationContent);
        notification.setNoticeType("message");
        notification.setSenderId(orders.getUserId());
        notification.setPriority(2);
        notification.setStatus(0);
        notification.setLink(link);
        notification.setCreateTime(new Date());
        notification.setUpdateTime(new Date());
        notification.setValidStart(new Date());
        MyMessage<Notification> notificationMyMessage = new MyMessage<>();
        notificationMyMessage.setMessage(notification);
        sendMessageUtils.sendMessage("message.exchange", "message.routingKey", notificationMyMessage);
        return null;
    }

    @Override
    public PageUtils<BackOrderDTO> selectAllOrders(int currentPage, int pageSize) {
        // 1. 查询总记录数
        QueryWrapper<Orders> countWrapper = new QueryWrapper<>();
        countWrapper.eq("status", 1);
        long total = ordersMapper.selectCount(countWrapper);

        // 2. 计算分页参数
        long offset = (currentPage - 1) * pageSize;

        // 3. 查询当前页数据
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        //查询status=0,1,2的订单
        queryWrapper.eq("status", 0)
                .or()
                .eq("status", 1)
                .or()
                .eq("status", 2)
                .orderByDesc("create_time")  // 按创建时间倒序
                .last("LIMIT " + offset + "," + pageSize);  // 使用MySQL的LIMIT语句
        ArrayList<BackOrderDTO> backOrderDTOS = new ArrayList<>();
        for (Orders orders : ordersMapper.selectList(queryWrapper)) {
            BackOrderDTO backOrderDTO = new BackOrderDTO();
            backOrderDTO.setOrdersId(orders.getOrdersId());
            backOrderDTO.setTradeNo(orders.getTransactionId());
            backOrderDTO.setCreateTime(DateTimeUtils.formatDateTime(orders.getCreateTime()));
            backOrderDTO.setCourseName(courseFeign.selectCourseByCourseIdForOrders(orders.getCourseId()).getTitle());
            backOrderDTO.setUserName(userService.getUserByUserId(orders.getUserId()).getUserName());
            backOrderDTO.setBuyerPayAmount(orders.getPaymentAmount().toString());
            backOrderDTO.setPaymentChannel(orders.getPaymentChannel());
            backOrderDTO.setOrderStatus(orders.getStatus() == 0 ? "待支付" : orders.getStatus() == 1 ? "支付成功" : "取消订单");
            backOrderDTO.setPayTime(DateTimeUtils.formatDateTime(orders.getPayTime()));
            backOrderDTOS.add(backOrderDTO);
        }


        // 4. 构建分页对象
        return new PageUtils<>(backOrderDTOS, total, pageSize, currentPage);
    }

    @Override
    public BackOrdersBoardDTO getOrdersBoard() {
        //总订单数
        BackOrdersBoardDTO backOrdersBoardDTO = new BackOrdersBoardDTO();
        backOrdersBoardDTO.setTotalOrders(ordersMapper.selectCount(null));
        //今日订单数
        backOrdersBoardDTO.setTodayOrders(ordersMapper.selectCount(new QueryWrapper<Orders>().apply("DATE(create_time) = CURDATE()")));
        //总收入
        backOrdersBoardDTO.setTotalIncome(
                ordersMapper.selectList(new QueryWrapper<Orders>()
                                .eq("status", 1))
                        .stream().map(Orders::getPaymentAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add));
        //今日收入
        backOrdersBoardDTO.setTodayIncome(
                ordersMapper.selectList(new QueryWrapper<Orders>()
                                .eq("status", 1)
                                .apply("DATE(create_time) = CURDATE()"))
                        .stream().map(Orders::getPaymentAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add));
        //待支付
        backOrdersBoardDTO.setWaitPay(ordersMapper.selectCount(new QueryWrapper<Orders>().eq("status", 0)));
        //支付成功
        backOrdersBoardDTO.setPaySuccess(ordersMapper.selectCount(new QueryWrapper<Orders>().eq("status", 1)));
        backOrdersBoardDTO.setCancelOrders(ordersMapper.selectCount(new QueryWrapper<Orders>().eq("status", 2)));
        return backOrdersBoardDTO;
    }

    @Override
    public DashboardTrendsDTO getDashboardTrends() {
        DashboardTrendsDTO dashboardTrendsDTO = new DashboardTrendsDTO();
        DashboardTrendsDTO.Trends trends = new DashboardTrendsDTO.Trends();
        //设置每日用户数据
        ArrayList<DashboardTrendsDTO.DailyUser> dailyUsers = new ArrayList<>();
        //查询7天用户数据
        List<User> todayUserCount = userService.getTodayUserCount();
        DashboardTrendsDTO.DailyUser dailyUser = new DashboardTrendsDTO.DailyUser();
        //今天的“yyyy-MM-dd”
        String today = DateTimeUtils.formatDate(new Date());
        dailyUser.setDate(today);
        if (todayUserCount == null) {
            dailyUser.setCount(0);
        } else {
            dailyUser.setCount(todayUserCount.size());
        }
        dailyUsers.add(dailyUser);
        trends.setDailyUsers(dailyUsers);
        //设置每日订单数据
        ArrayList<DashboardTrendsDTO.DailyOrder> dailyOrders = new ArrayList<>();
        DashboardTrendsDTO.DailyOrder dailyOrder = new DashboardTrendsDTO.DailyOrder();
        dailyOrder.setDate(today);
        dailyOrder.setCount(ordersMapper.selectCount(new QueryWrapper<Orders>().apply("DATE(create_time) = CURDATE()")));
        dailyOrder.setAmount(ordersMapper.selectList(new QueryWrapper<Orders>().apply("DATE(create_time) = CURDATE()"))
                .stream().map(Orders::getPaymentAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        dailyOrders.add(dailyOrder);
        trends.setDailyOrders(dailyOrders);
        //设置每日收入数据
        ArrayList<DashboardTrendsDTO.DailyRevenue> dailyRevenues = new ArrayList<>();
        DashboardTrendsDTO.DailyRevenue dailyRevenue = new DashboardTrendsDTO.DailyRevenue();
        dailyRevenue.setDate(today);
        dailyRevenue.setAmount(ordersMapper.selectList(new QueryWrapper<Orders>().apply("DATE(create_time) = CURDATE()"))
                .stream().map(Orders::getPaymentAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        dailyRevenues.add(dailyRevenue);
        trends.setDailyRevenue(dailyRevenues);
        dashboardTrendsDTO.setTrends(trends);
        return dashboardTrendsDTO;

    }


}




